﻿using Autofac;
using AutoFacBasic.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace AutoFacBasic
{
    public class Program
    {
        static void Main(string[] args)
        {
            //创建容器
            ContainerBuilder builder = new ContainerBuilder();


            //1.按类型注册
            builder.RegisterType<Student>().As<IStudent>();
            builder.RegisterType<Student>().AsImplementedInterfaces();
            IContainer container = builder.Build();
            container.Resolve<IStudent>().Learn("学习了按类型注册");

            //2.按文本/名称注册
            builder = new ContainerBuilder();
            builder.RegisterType<Student>().Named<IStudent>("A");
            builder.RegisterType<Student>().Named<IStudent>("B");
            container = builder.Build();
            var student1 = container.ResolveNamed<IStudent>("A");
            student1.Name = "张三";
            student1.Learn("学习了按名字注册");
            var student2 = container.ResolveNamed<IStudent>("B");
            student2.Name = "李四";
            student2.Learn("学习了按名字注册");

            //3.按枚举注册
            builder = new ContainerBuilder();
            builder.RegisterType<Student>().Keyed<IStudent>(StudentType.Mid);
            builder.RegisterType<Student>().Keyed<IStudent>(StudentType.Sup);
            container = builder.Build();
            student1 = container.ResolveKeyed<IStudent>(StudentType.Mid);
            student1.Name = "王五";
            student1.Learn("学习了按枚举注册");
            student2 = container.ResolveKeyed<IStudent>(StudentType.Sup);
            student2.Name = "赵六";
            student2.Learn("学习了按枚举注册");

            //4.注册实例单例
            builder = new ContainerBuilder();
            builder.RegisterInstance<IStudent>(new Student());
            builder.RegisterInstance(new Student()).Named<Student>("AA");
            container = builder.Build();
            IStudent student = container.Resolve<IStudent>();
            student.Learn("注册了实例");

            //5.Lanmda注册
            builder = new ContainerBuilder();
            builder.Register(c => new Student()).As<IStudent>();
            container = builder.Build();
            IStudent studentlmd = container.Resolve<IStudent>();
            student.Learn("Lanmda注册");

            //6.Lanmda多样化注册
            builder = new ContainerBuilder();
            builder.Register<IStudent>((c, p) =>
            {
                var type = p.Named<string>("type");
                if (type == "Dog")
                {
                    return new Student();
                }
                else
                {
                    return new Student();
                }
            }).As<IStudent>();
            container = builder.Build();
            var dog = container.Resolve<IStudent>(new NamedParameter("type", "Dog"));
            dog.Learn("Lanmda多样化注册");

            //7.程序集注册
            builder = new ContainerBuilder();
            Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service");   //实现类所在的程序集名称
            builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();  //常用
            //builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency();    //常用
            //builder.RegisterAssemblyTypes(assembly).Where(t=>t.Name.StartsWith("S")).AsImplementedInterfaces();  //带筛选
            //builder.RegisterAssemblyTypes(assembly).Except<s>().AsImplementedInterfaces();  //带筛选
            container = builder.Build();

            //8.实例集合注册
            builder = new ContainerBuilder();
            builder.RegisterInstance<List<IStudent>>(new List<IStudent>() { new Student() { Name = "张三" }, new Student() { Name = "李四" } });
            container = builder.Build();
            List<IStudent> animals = container.Resolve<List<IStudent>>();
            foreach (var item in animals)
            {
                item.Learn("实例集合注册");
            }

            //9.泛型注册
            builder = new ContainerBuilder();
            builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>));
            container = builder.Build();
            IList<string> list = container.Resolve<IList<string>>();

            //10.非覆盖注册
            builder = new ContainerBuilder();
            builder.RegisterInstance<IStudent>(new Student() { Name = "张三" });
            builder.RegisterInstance<IStudent>(new Student() { Name = "李四" }).PreserveExistingDefaults();  //指定为非默认值
            container = builder.Build();
            student = container.Resolve<IStudent>();
            student.Learn("非覆盖注册");


            //11.生命周期注入的生命周期
            builder = new ContainerBuilder();
            builder.RegisterType<Student>().As<IStudent>().InstancePerLifetimeScope();
            container = builder.Build();

            IStudent s1 = container.Resolve<IStudent>();
            IStudent s2 = container.Resolve<IStudent>();
            Console.WriteLine(s1.Equals(s2));
            using (ILifetimeScope lifetime = container.BeginLifetimeScope())
            {
                IStudent s3 = lifetime.Resolve<IStudent>();
                IStudent s4 = lifetime.Resolve<IStudent>();
                Console.WriteLine(s3.Equals(s4));
                Console.WriteLine(s2.Equals(s3));
            }
        }
    }

    public enum StudentType
    {
        Mid,
        Sup
    }
}
